package com.mz.mattress.admin.service.impl;

import com.github.binarywang.wxpay.bean.transfer.TransferBillsCancelResult;
import com.github.binarywang.wxpay.bean.transfer.TransferBillsGetResult;
import com.github.binarywang.wxpay.bean.transfer.TransferBillsRequest;
import com.github.binarywang.wxpay.bean.transfer.TransferBillsResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.mz.mattress.admin.api.resp.CashOutResp;
import com.mz.mattress.admin.mapper.MemberBalanceRecordMapper;
import com.mz.mattress.admin.mapper.MemberCashOutOrderMapper;
import com.mz.mattress.admin.mapper.MemberMerMapper;
import com.mz.mattress.admin.service.HongBaoService;
import com.mz.mattress.admin.service.MemberMerService;
import com.mz.mattress.api.redis.RedisKeys;
import com.mz.mattress.api.common.Result;
import com.mz.mattress.api.entity.MemberBalanceRecord;
import com.mz.mattress.api.entity.MemberCashOutOrder;
import com.mz.mattress.api.entity.MemberMer;
import com.mz.mattress.api.util.IdUtil;
import com.mz.mattress.api.util.MathUtil;
import com.mz.mattress.api.util.StringTools;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.concurrent.TimeUnit;


@Slf4j
@Service
public class HongBaoServiceImpl implements HongBaoService {

    @Autowired
    private MemberMerMapper memberMerMapper;

    @Autowired
    private WxPayService wxPayService;

    @Autowired
    private MemberCashOutOrderMapper memberCashOutOrderMapper;

    @Autowired
    private MemberMerService memberMerService;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private MemberBalanceRecordMapper memberBalanceRecordMapper;

    @Override
    public Result<CashOutResp> cashOut(Long memberId, Integer money, String ip) {

        if (money < 1000 || money > 20000) {
            return Result.fail("提现金额在10-200元之间");
        }

        MemberMer memberMer = memberMerMapper.selectById(memberId);
        if (memberMer == null) {
            log.error("not_find_member,memberId=" + memberId);
            return Result.fail("未找到用户");
        }

        if (memberMer.getBalance() < money) {
            return Result.fail("提现余额不足");
        }

        String openId = memberMer.getOpenId();
        if (StringTools.isEmpty(openId)) {
            return Result.fail("找不到用户信息");
        }

        TransferBillsRequest.TransferSceneReportInfo info1 = new TransferBillsRequest.TransferSceneReportInfo();
        info1.setInfoType("岗位类型");
//            info1.setInfoContent("外卖员");
        info1.setInfoContent("销售员");

        TransferBillsRequest.TransferSceneReportInfo info2 = new TransferBillsRequest.TransferSceneReportInfo();
        info2.setInfoType("报酬说明");
//            info2.setInfoContent("7月份配送费");
        info2.setInfoContent("佣金收入");

//            佣金报酬
//            ID:1005
//            向劳务提供方，如销售、团长、主播支付佣金、报酬等

        ArrayList<TransferBillsRequest.TransferSceneReportInfo> list = new ArrayList<>();
        list.add(info1);
        list.add(info2);

        String cashId = IdUtil.generateSsn();
        log.info("cashId={},memberId={},money={}", cashId, memberId, money);

        //微信千分之6手续费
        Integer fee = MathUtil.wxFee(money);
        //真实到手金额
        Integer bonus = money - fee;

        TransferBillsRequest request = TransferBillsRequest.newBuilder()
//                    .appid("wxdcedcd0014be9e99")
                .appid(APP_ID)
                .outBillNo(cashId)
                .transferSceneId("1005")
                .transferSceneReportInfos(list)
                .transferAmount(bonus)
                .transferRemark("佣金提现")
                .openid(openId).build();
//                    .userName("徐顺望").build();
        TransferBillsResult result = null;
        try {
            result = wxPayService.getTransferService().transferBills(request);

            //冻结金额 乐观锁
            Integer count = memberMerMapper.freezeMoney(memberId, money, memberMer.getVersion());
            if (count <= 0) {
                log.info("freezeMoney_fail,memberId={},money={}", memberId, money);
                return Result.fail("请稍后再试");
            }

            //添加提现请求记录
            MemberCashOutOrder order = new MemberCashOutOrder();
            order.setMemberId(memberId);
            order.setName(memberMer.getName());
            order.setMobile(memberMer.getMobile());
            order.setType(memberMer.getType());
            order.setOpenId(openId);
            order.setAmount(money);
            order.setFee(fee);
            order.setAppId(APP_ID);
            order.setCashId(cashId);
            order.setDone(0);
            memberCashOutOrderMapper.insert(order);

            //redis 过期消息， 三分钟内未确认，关闭订单
            String cashOutKey = RedisKeys.getCashOutKey(cashId);
            redisTemplate.opsForValue().set(cashOutKey, money, 2, TimeUnit.MINUTES);

        } catch (WxPayException e) {
            String message = e.getMessage();
            log.info("cashOut_error=" + message);
            return Result.fail(e.getMessage());
        }

        String packageInfo = result.getPackageInfo();
        CashOutResp resp = new CashOutResp();
        resp.setPackageInfo(packageInfo);
        resp.setCashId(cashId);

        return Result.ok(resp);

    }

    @Override
    public Result<String> queryIsPaid(String cashId) {

        TransferBillsGetResult result = null;
        try {
            result = wxPayService.getTransferService().getBillsByOutBillNo(cashId);
            log.info("cashId={},result={}", cashId, result.getState());
        } catch (WxPayException e) {
            String message = e.getMessage();
            log.info("queryPaid_error=" + message);
            return Result.fail(e.getMessage());
        }

        MemberCashOutOrder order = memberCashOutOrderMapper.selectByCashId(cashId);
        if (order == null) {
            return Result.fail("找不到记录");
        }

        if (order.getDone() == 1) {
            return Result.fail("已完成");
        }

        if (result.getState().equals(SUCCESS)) {

            //提现成功
            //按提现金额 扣钱
            Result cash = memberMerService.cashOut(order.getMemberId(), cashId, order.getAmount());
            if (cash.isFail()) {
                log.error("cash_out_error,cashId={},member={}", cashId, order.getMemberId());
                return cash;
            }

            MemberCashOutOrder update = new MemberCashOutOrder();
            update.setId(order.getId());
            update.setState(result.getState());
            update.setTransferBillNo(result.getTransferBillNo());
            //实际到手金额
            update.setTransferAmount(result.getTransferAmount());
            update.setFailReason(result.getFailReason());
            update.setUserName(result.getUserName());
            update.setDone(1);
            memberCashOutOrderMapper.updateById(update);

        }

        return Result.ok(result.getState());
    }

    @Override
    public Result closeCashOutOrder(String cashId) {

        MemberCashOutOrder order = memberCashOutOrderMapper.selectByCashId(cashId);
        if (order == null) {
            return Result.fail("找不到记录");
        }

        if (order.getDone() == 1) {
            return Result.fail("已完成");
        }

        MemberMer memberMer = memberMerMapper.selectById(order.getMemberId());
        if (memberMer == null) {
            log.error("not_find_member,memberId=" + order.getMemberId());
            return Result.fail("找不到用户");
        }

        //释放冻结金额
        Integer count = memberMerMapper.freezeRelease(order.getMemberId(), order.getAmount(), memberMer.getVersion());
        if (count <= 0) {
            log.info("freezeRelease_failed,memberId={},amount={}", order.getMemberId(), order.getAmount());
            return Result.fail("请稍后再试");
        }

        MemberBalanceRecord record = new MemberBalanceRecord();
        record.setMemberId(order.getMemberId());
        record.setBalance(memberMer.getBalance());
        record.setChanges(order.getAmount());
        record.setAfters(memberMer.getBalance() + order.getAmount());
        record.setCashId(cashId);
        record.setRemark("提现金额退回");
        memberBalanceRecordMapper.insert(record);

        try {
            TransferBillsCancelResult result = wxPayService.getTransferService().transformBillsCancel(cashId);
            log.info("closeCashOutOrder_result,cashId={},state={}", cashId, result.getState());

            //标记已完成
            MemberCashOutOrder update = new MemberCashOutOrder();
            update.setId(order.getId());
            update.setState("CLOSE");
            update.setDone(1);
            memberCashOutOrderMapper.updateById(update);

        } catch (WxPayException e) {
            String message = e.getMessage();
            log.info("closeCashOutOrder_error=" + message);
            return Result.fail(e.getMessage());
        }
        return Result.ok();
    }

//    9921d4ac74a9431d8d737c83201aadf4

    public static void main(String[] args) {

        Integer bonus = MathUtil.wxFee(1500);
        System.out.println(bonus);

        System.out.println("1330001447768472507140091550813388".length());
    }
}
